﻿#include "GY_IdTreeView.h"
#include "CustomFilterModule.h"
GY_IdTreeView::GY_IdTreeView(QWidget *parent)
    : QTreeView(parent),m_IsCheckable(false)
{
    m_pModel= new QStandardItemModel(this);
    //创建自定义代理模型
    m_pFilter = new CustomFilterModule(this);
    m_pFilter->setSourceModel(m_pModel);
    this->setModel(m_pFilter);
    connect(m_pModel,&QStandardItemModel::dataChanged,this,&GY_IdTreeView::cellDataChangeSlot);
}

GY_IdTreeView::~GY_IdTreeView()
{
    if(nullptr != m_pModel)
    {
        delete m_pModel;
    }
}
//-------------------------列编辑接口--------------------------------
/**
 * @brief setColumnCount 设置列数
 * @param columnCount 添加的列数
 */
void GY_IdTreeView::setColumnCount(const int columnCount)
{
    if(!m_pModel ||columnCount<0||m_pModel->columnCount()==columnCount)
    {
        return;
    }
    else if(0==columnCount)
    {
        m_TreeNodeInfo.clear();
        if(nullptr!=m_pModel)
        {
            m_pModel->clear();
        }
        return;
    }
    int treeColumnCount=m_pModel->columnCount();
    for(int i=qMin(columnCount,treeColumnCount);i<columnCount;i++)
    {
        if(i+1>treeColumnCount)
        {
            addColumn(QString("标题%1").arg(i+1));
        }
        else
        {
            deleteColumn(qMin(columnCount,treeColumnCount));
        }
    }
}
/**
 * @brief addColumn 添加空白列
 * @param columnName 添加的列名
 */
void GY_IdTreeView::addColumn(const QString &columnName)
{
    if(!m_pModel ||columnName==nullptr) //设置列名为空无效
    {
        return;
    }
    int column = m_pModel->columnCount();
    m_pModel->setHorizontalHeaderItem(m_pModel->columnCount(),new QStandardItem(columnName));
    foreach(QList<QStandardItem*> dataItemList,m_TreeNodeInfo)
    {
        if(nullptr!=dataItemList[0]->parent()&&dataItemList[0]->parent()->columnCount()!=m_pModel->columnCount())
        {
            m_pModel->insertColumns(column,1,dataItemList[0]->parent()->index());
        }
        m_TreeNodeInfo[dataItemList[0]->data(TreeDataType::RowIdData)].append(m_pModel->itemFromIndex(dataItemList[0]->index().siblingAtColumn(column)));
    }
}
/**
 * @brief insterColumn 插入列
 * @param index 插入在第几列
 * @param columnName 插入的列名
 * @return 返回插入列是否成功
 */
bool GY_IdTreeView::insertColumn(const int index, const QString &columnName)
{
    if(!m_pModel || index<0 || index>m_pModel->columnCount())
    {
        return false;
    }
    //获取之前的列头
    QStringList strList;
    for(int i=0;i<m_pModel->columnCount();i++)
    {
       strList<<m_pModel->headerData(i,Qt::Horizontal).toString();
    }
    strList.insert(index,columnName);
    int actualIndex = index;
    //判定插入到0列就实际插入到1列
    if(0<m_pModel->columnCount()&&0==index)
    {
        actualIndex=1;
    }
     m_pModel->insertColumn(actualIndex);
     m_pModel->setHorizontalHeaderLabels(strList);

    for(QMap<QVariant,QList<QStandardItem*>>::iterator iter = m_TreeNodeInfo.begin(); iter != m_TreeNodeInfo.end();iter++)
    {
        QStandardItem* pItem=m_pModel->itemFromIndex(iter.value()[0]->index().siblingAtColumn(actualIndex));
        if(nullptr!=iter.value()[0]->parent()&&iter.value()[0]->parent()->columnCount()!=m_pModel->columnCount())
        {
            m_pModel->insertColumn(actualIndex,iter.value()[0]->parent()->index());
        }
        if(index == 0)
        {
            m_pModel->blockSignals(true);
            pItem->setData(iter.value()[0]->data(TreeDataType::DisplayData),TreeDataType::DisplayData);
            pItem->setData(iter.value()[0]->data(TreeDataType::TransferData),TreeDataType::TransferData);
            iter.value()[0]->setData(QVariant(),TreeDataType::DisplayData);
            iter.value()[0]->setData(QVariant(),TreeDataType::TransferData);
            m_pModel->blockSignals(false);
        }
        iter.value().insert(index,pItem);
    }

    viewport()->update();
    this->update();
    this->repaint();
    return true;
}
/**
 * @brief deleteColumn 删除列
 * @param index 列索引
 * @return 返回删除列是否成功
 */
bool GY_IdTreeView::deleteColumn(const int index)
{
    if(m_pModel==nullptr ||index<0 || index>m_pModel->columnCount())
    {
        return false;
    }
    int actualIndex = index;
    //如果删除的是第一列将RowID重新赋值给新的第一列
    if(!index&&m_pModel->columnCount()>0)
    {
        actualIndex=1;
        m_pModel->blockSignals(true);
        foreach(QList<QStandardItem*> itemList,m_TreeNodeInfo)
        {
            itemList[0]->setData(itemList[1]->data(TreeDataType::DisplayData),TreeDataType::DisplayData);
            itemList[0]->setData(itemList[1]->data(TreeDataType::TransferData),TreeDataType::TransferData);
        }
        m_pModel->blockSignals(false);
        viewport()->update();
    }
    m_pModel->blockSignals(true);
    //删除信息记录
    for(QMap<QVariant,QList<QStandardItem*>>::iterator iter = m_TreeNodeInfo.begin(); iter != m_TreeNodeInfo.end();iter++)
    {
        if(iter.value()[0]->hasChildren())
        {
            iter.value()[0]->removeColumn(actualIndex);
        }
        iter.value().removeAt(actualIndex);
    }
    m_pModel->removeColumn(actualIndex);
    m_pModel->blockSignals(false);
    viewport()->update();
    this->update();
    this->repaint();
    //如果判定已经删除了所有列便清空Map
    if(!m_pModel->columnCount())
    {
        m_TreeNodeInfo.clear();
    }
    return true;
}
/**
 * @brief setColumnHeadName  设置列头名称
 * @param nameList  要修改的列名集
 */
void GY_IdTreeView::setColumnHeadName(const QStringList &nameList)
{
    if(nameList.size()<0 || !m_pModel)
    {
        return;
    }
    QStringList headNames;
    for(int i=0;i<m_pModel->columnCount();i++)
    {
        if(i<nameList.size())//如果原列表列数小于新设置的列名数量
        {
            headNames<< nameList.at(i);
        }
        else
        {
            headNames<< m_pModel->horizontalHeaderItem(i)->text();//将原列表列名补充进新列名中
        }
    }
    m_pModel->setHorizontalHeaderLabels(headNames); //将列名导入列表中
}
/**
* @brief addRowData 添加行
* @param rowId 行Id
* @param rowData 行数据
* @return返回是否添加成功
*/
void GY_IdTreeView::setColumnHeadName(const int index, const QString &headName)
{
    if(index>=m_pModel->columnCount()||index<0)
    {
        return;
    }
    QStandardItem* pitem = new QStandardItem(headName);
    m_pModel->setHorizontalHeaderItem(index,pitem); //索引修改列名
}
//-------------------------列编辑接口--------------------------------
/**
 * @brief addRowData  添加行数据
 * @param rowId 行Id
 * @param rowData 行数据
 * @param nodeParentId 父级Id
 * @param nodeType 节点类型
 * @return 返回添加是否成功
 */
bool GY_IdTreeView::addRowData(const QVariant &rowId, const QVector<QVariant> &rowData, const QVariant &nodeParentId, const QVariant &nodeType)
{
    if(m_TreeNodeInfo.contains(rowId)||!rowData.size()||!m_pModel||!m_pModel->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> rowItems;
    int columnCount = m_pModel->columnCount();
    for(int i=0;i<qMin(columnCount,rowData.count());i++)
    {
        QStandardItem* pItem=new QStandardItem;
        pItem->setData(rowData[i],TreeDataType::TransferData);
        pItem->setText(rowData[i].toString());
        //在第一列设置行ID 节点类型 父级ID
        if(i==0)
        {
            pItem->setData(nodeType,TreeDataType::NodeTypeData);
            pItem->setData(rowId,TreeDataType::RowIdData);
            //设置图标
            if(m_NodeTypeToIconMap.contains(nodeType)&&!m_NodeTypeToIconMap.value(nodeType).isNull())
            {
                pItem->setIcon(m_NodeTypeToIconMap.value(nodeType));
            }
            //设置复选框
            if(m_IsCheckable)
            {
                pItem->setCheckable(true);
            }
        }
        rowItems<<pItem;
    }
    //判定顶层节点是否存在
    if(m_TreeNodeInfo.contains(nodeParentId))
    {
        m_TreeNodeInfo[nodeParentId][0]->appendRow(rowItems);
    }
    else //若不存在，则直接在根结点后添加一行数据
    {
        m_pModel->appendRow(rowItems);
    }
    m_TreeNodeInfo.insert(rowId,rowItems);
    return true;
}
/**
 * @brief insertRowData   插入行数据
 * @param rowId 节点id
 * @param rowData 插入的行数据
 * @param index 引索第几个
 * @param nodeParentId 父级Id
 * @param nodeType 节点类型
 * @return 返回插入行数据是否成功
 */
bool GY_IdTreeView::insertRowData(const QVariant &rowId, const QVector<QVariant> &rowData, const int index, const QVariant &nodeParentId, const QVariant nodeType)
{
    if(m_TreeNodeInfo.contains(rowId)||!rowData.size()||!m_pModel||!m_pModel->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> rowItems;
    int columnCount = m_pModel->columnCount();
    for(int i=0;i<qMin(columnCount,rowData.count());i++)
    {
        QStandardItem* pItem=new QStandardItem;
        pItem->setData(rowData[i],TreeDataType::TransferData);
        pItem->setText(rowData[i].toString());
        //在第一列设置行ID 节点类型
        if(i==0)
        {
            pItem->setData(nodeType,TreeDataType::NodeTypeData);
            pItem->setData(rowId,TreeDataType::RowIdData);
            //设置图标
            if(m_NodeTypeToIconMap.contains(nodeType)&&!m_NodeTypeToIconMap.value(nodeType).isNull())
            {
                pItem->setIcon(m_NodeTypeToIconMap.value(nodeType));
            }
            //设置复选框
            if(m_IsCheckable)
            {
                pItem->setCheckable(true);
            }
        }
        rowItems<<pItem;
    }
    //判定顶层节点是否存在
    if(m_TreeNodeInfo.contains(nodeParentId))
    {
        QStandardItem* pParentItem = m_TreeNodeInfo.value(nodeParentId)[0];
        if(index<pParentItem->rowCount())
        {
            pParentItem->insertRow(index,rowItems);
        }
        else
        {
            pParentItem->appendRow(rowItems);
        }
        m_TreeNodeInfo[nodeParentId][0]->appendRow(rowItems);
    }
    else //若不存在，则直接在根结点后添加一行数据
    {
        if(m_pModel->rowCount()>index)
        {
            m_pModel->insertRow(index,rowItems);
        }
        else
        {
            m_pModel->appendRow(rowItems);
        }
    }
    m_TreeNodeInfo.insert(rowId,rowItems);
    return true;
}
/**
 * @brief deleteRow  删除指定行
 * @param id 删除行的id号
 * @return 返回删除是否成功
 */
void GY_IdTreeView::deleteRow(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return ;
    }
    QList<QStandardItem*> nodeItemList= m_TreeNodeInfo.value(rowId);
    //从记录上移除
    m_TreeNodeInfo.remove(rowId);
    for(int i=0;i<nodeItemList[0]->rowCount();i++)
    {
        deleteRow(nodeItemList[0]->child(i)->data(TreeDataType::RowIdData));
    }
    //移除控件
    if(!nodeItemList[0]->parent())
    {
        m_pModel->removeRow(nodeItemList[0]->index().row());
    }
    else
    {
        nodeItemList[0]->parent()->removeRow(nodeItemList[0]->index().row());
    }
}

/**
 * @brief GY_IdTreeView::getParentRowId 获取父级行Id
 * @param rowId 行Id
 * @return 父级行Id
 */
QVariant GY_IdTreeView::getParentRowId(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId)||m_TreeNodeInfo[rowId][0]->parent()==nullptr){
        return QVariant();
    }
    return m_TreeNodeInfo[rowId][0]->parent()->data(TreeDataType::RowIdData);
}

/**
 * @brief clearData 清除所有数据
 */
void GY_IdTreeView::clearData()
{
//    for(int rowIndex=0;rowIndex<m_pModel->rowCount();rowIndex++)
//    {
//        QList<QStandardItem*> itemList=m_pModel->takeRow(rowIndex);
//        deleteRow(itemList[0]->data(TreeDataType::RowIdData));
//    }
    m_pModel->clear();
    m_TreeNodeInfo.clear();
}
/**
 * @brief setRowData  修改行数据
 * @param rowId  修改行id
 * @param rowData  要修改的数据
 * @return 是否修改成功
 */
bool GY_IdTreeView::setRowData(const QVariant &rowId, const QVector<QVariant> &rowData)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    for(int i=0;i<qMin(rowData.size(),m_TreeNodeInfo.value(rowId).size());i++)
    {
        m_TreeNodeInfo[rowId][i]->setData(rowData[i]);
        m_TreeNodeInfo[rowId][i]->setText(rowData[i].toString());
    }
    return true;
}
/**
 * @brief setRowNodeType 设置节点类型
 * @param rowId 行ID
 * @param nodeType 节点类型
 * @return 是否设置成功
 */
bool GY_IdTreeView::setRowNodeType(const QVariant &rowId, const QVariant &nodeType)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    m_TreeNodeInfo[rowId][0]->setData(nodeType,TreeDataType::NodeTypeData);
    if(m_NodeTypeToIconMap.contains(nodeType))
    {
        m_TreeNodeInfo[rowId][0]->setIcon(m_NodeTypeToIconMap.value(nodeType));
    }
    return true;
}
/**
* @brief getRowNodeType 根据节点查找类型
* @param rowId 行Id
* @return 返回对应type
*/
QVariant GY_IdTreeView::getRowNodeType(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    return m_TreeNodeInfo.value(rowId).at(0)->data(TreeDataType::NodeTypeData);
}

/**
 * @brief GY_IdTreeView::getRowData 获取行数据
 * @param rowId 行Id
 * @param rowData 返回的行数据
 * @return 成功/失败
 */
bool GY_IdTreeView::getRowData(const QVariant &rowId, QVector<QVariant> &rowData)
{
    if(!m_TreeNodeInfo.contains(rowId)){
        return false;
    }
    for(int i=0; i<m_TreeNodeInfo[rowId].size(); ++i){
        rowData<<m_TreeNodeInfo[rowId][i]->data(TreeDataType::TransferData);
    }
    return true;
}

/**
 * @brief GY_IdTreeView::getRowIndex 获取行索引
 * @param rowId 行Id
 * @param index 所在父级下，该行的索引
 * @param parentRowId 父级rowId
 * @return 成功/失败
 */
bool GY_IdTreeView::getRowIndex(const QVariant &rowId, int &index, QVariant &parentRowId)
{
    if(!m_TreeNodeInfo.contains(rowId)){
        return false;
    }
    index = m_TreeNodeInfo[rowId][0]->index().row();
    parentRowId =QVariant();
    if(m_TreeNodeInfo[rowId][0]->index().parent().isValid()){
        parentRowId=m_TreeNodeInfo[rowId][0]->index().parent().data(TreeDataType::RowIdData);
    }
    return true;
}
//-------------------------单元格编辑接口--------------------------------
/**
 * @brief setRowNodeType 设置节点类型
 * @param rowId 行ID
 * @param nodeType 节点类型
 * @return 是否设置成功
 */
bool GY_IdTreeView::setCellColor(const QVariant &rowId, const int columnIndex, const QColor &color)
{
    if(!m_TreeNodeInfo.contains(rowId)||columnIndex>=m_TreeNodeInfo.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    QBrush abrush;
    abrush.setColor(color);
    m_TreeNodeInfo.value(rowId).at(columnIndex)->setBackground(abrush);
    return true;
}
/**
 * @brief setCellData  修改单元格数据
 * @param rowId 修改行Id
 * @param columnIndex  修改列索引
 * @param cellData  要修改的数据
 * @param role 修改的数据类型
 * @return 是否修改成功
 */
bool GY_IdTreeView::setCellData(const QVariant &rowId, const int columnIndex, const QVariant &cellData, int role)
{
    if(!m_TreeNodeInfo.contains(rowId)||columnIndex>=m_TreeNodeInfo.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_TreeNodeInfo.value(rowId).at(columnIndex)->setData(cellData,role);
    return true;
}
/**
 * @brief setCellText 设置单元格文字
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @param displayText 显示文字
 * @return 是否设置成功
 */
bool GY_IdTreeView::setCellText(const QVariant &rowId, const int columnIndex, const QString &displayText)
{
    return setCellData(rowId,columnIndex,displayText,TreeDataType::DisplayData);
}
/**
 * @brief getCellData 获取单元格数据
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @return 单元格数据
 */
QVariant GY_IdTreeView::getCellData(const QVariant &rowId, const int columnIndex, int role)
{
    QVariant cellData;
    if(!m_TreeNodeInfo.contains(rowId)||columnIndex>=m_TreeNodeInfo.value(rowId).size()||columnIndex<0)
    {
        return cellData;
    }
    cellData=m_TreeNodeInfo.value(rowId).at(columnIndex)->data(role);
    return cellData;
}
/**
 * @brief getCellText 获取单元格文字
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @return 单元格文字
 */
QString GY_IdTreeView::getCellText(const QVariant &rowId, const int columnIndex)
{
    return getCellData(rowId,columnIndex,TreeDataType::DisplayData).toString();
}
/**
 * @brief setCellEnabled 设置单元格交互状态
 * @param rowId  行ID
 * @param columnIndex 列索引
 * @param isEnabled 是否可交互
 * @return 返回设置是否成功
 */
bool GY_IdTreeView::setCellEnabled(const QVariant &rowId, const int columnIndex, const bool isEnabled)
{
    if(!m_TreeNodeInfo.contains(rowId)||columnIndex>=m_TreeNodeInfo.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_TreeNodeInfo.value(rowId).at(columnIndex)->setEnabled(isEnabled);
    return true;
}
/**
 * @brief setCellEditabled 设置单元格编辑状态
 * @param rowId  行ID
 * @param columnIndex 列索引
 * @param isEnabled 是否可编辑
 * @return 返回设置是否成功
 */
bool GY_IdTreeView::setCellEditabled(const QVariant &rowId, const int columnIndex, const bool isEditabled)
{
    if(!m_TreeNodeInfo.contains(rowId)||columnIndex>=m_TreeNodeInfo.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_TreeNodeInfo.value(rowId).at(columnIndex)->setEditable(isEditabled);
    return true;
}
//-------------------------过滤接口--------------------------------
/**
 * @brief GY_IdTableView::setFilterRegExp 设置搜索过滤正则表达式
 * @param searchText 搜索过滤文本
 */
void GY_IdTreeView::setFilterRegExp(const QString &searchText)
{
    m_pFilter->setFilterRegExp(searchText);
}
//-------------------------图标接口--------------------------------
/**
 * @brief setNodeTypeIcon 设置节点类型图标
 * @param nodeType 节点类型
 * @param icon 图标
 */
void GY_IdTreeView::setNodeTypeIcon(const QVariant &nodeType, const QIcon &icon)
{
    m_NodeTypeToIconMap.insert(nodeType,icon);
    //设置已有节点的图标
    foreach(QList<QStandardItem*> itemList,m_TreeNodeInfo)
    {
        if(itemList[0]->data(TreeDataType::NodeTypeData)==nodeType)
        {
            itemList[0]->setIcon(icon);
        }
    }
}

//---------------------------选择接口-----------------------------------
/**
 * @brief currentChanged 当前选择变化
 * @param current 当前选择的索引
 * @param previous 之前选择的索引
 */
void GY_IdTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
   QVariant currentId= current.siblingAtColumn(0).data(TreeDataType::RowIdData);
   QVariant previousId= previous.siblingAtColumn(0).data(TreeDataType::RowIdData);
   if(previous==currentId)
   {
        emit selectRowChangeSignal(currentId);
   }
   emit selectCellChangeSignal(currentId,current.column());
}
/**
 * @brief getSelecRowId  获取选择行id
 * @return  多选下返回选中的第一行
 */
QVariant GY_IdTreeView::getSelectRowId()
{
    return currentIndex().siblingAtColumn(0).data(TreeDataType::RowIdData);
}

/**
 * @brief getSelectCellColunmIndex 获取选择单元格索引
 * @return 返回选择单元格索引
 */
int GY_IdTreeView::getSelectCellColunmIndex()
{
    return currentIndex().column();
}
/**
 * @brief getSelectRowIds 获取选择行id
 * @return  返回选择的id，单选时返回一个id
 */
QVector<QVariant> GY_IdTreeView::getSelectRowIds()
{
    QModelIndexList selected = this->selectionModel()->selectedRows(); //获取选中行
    QVector<QVariant> selectedRowIds;
    for(int i=0;i<selected.size();i++)
    {
        selectedRowIds<< selected.at(i).siblingAtColumn(0).data(TreeDataType::RowIdData);
    }
    return  selectedRowIds;
}
/**
 * @brief setRowSelectState 设置行选择状态
 * @param rowId 节点ID
 * @param isSelect 该行是否选择
 * @return 是否设置成功
 */
bool GY_IdTreeView::setRowSelectState(const QVariant &rowId, const bool isSelect)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    selectionModel()->select(m_TreeNodeInfo.value(rowId)[0]->index(),(isSelect?(QItemSelectionModel::Select):(QItemSelectionModel::Deselect)) | QItemSelectionModel::Rows);
    return true;
}
//-----------------------------展开接口-----------------------------------------
/**
 * @brief setRowExpendState 设置行单层展开模式
 * @param rowId  行id
 * @param isExpend 是否展开
 * @return 是否展开该行
 */
bool GY_IdTreeView::setRowExpendState(const QVariant &rowId, const bool isExpend)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    this->setExpanded(m_TreeNodeInfo.value(rowId)[0]->index(),isExpend); //设置是否展开
    return true;
}
/**
 * @brief setAllChildRowExpendState 设置所有子行全部展开模式
 * @param rowId  行id
 * @param isExpend 是否展开
 * @return 是否展开该行
 */
bool GY_IdTreeView::setAllChildRowExpendState(const QVariant &rowId, const bool isExpend)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)[0];
    setAllChildNodeExpentState(pItem,isExpend); //展开该id所有子节点
    if(isExpend)
    {
        updateTopParentNodeExpentState(pItem); //递归展开该id父节点
    }
    return true;
}
/**
 * @brief setAllChildNodeExpentState 设置所有子节点展开状态
 * @param pItem 当前节点的Item
 * @param isExpend 是否展开
 */
void GY_IdTreeView::setAllChildNodeExpentState(QStandardItem *pItem, bool isExpend)
{
    if(nullptr==pItem) //判断item是否存在
    {
        return;
    }
    setExpanded(pItem->index(),isExpend);
    for(int i=0;i<pItem->rowCount();i++)
    {
        setAllChildNodeExpentState(pItem->child(i),isExpend);
    }
}
/**
 * @brief updateTopParentNodeExpentState 跟新递归至顶层的所有父级节点的展开状态
 * @param pItem 当前节点item
 */
void GY_IdTreeView::updateTopParentNodeExpentState(QStandardItem *pItem)
{
    if(nullptr==pItem)
    {
        return;
    }
    this->setExpanded(pItem->index(),true);
    updateTopParentNodeExpentState(pItem->parent());
}
/**
 * @brief getExpentState 获取展开状态
 * @param rowId 行id
 * @return 返回是否展开
 */
bool GY_IdTreeView::getExpentState(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    return isExpanded(m_TreeNodeInfo.value(rowId)[0]->index());
}
/**
 * @brief setAllRowExpendState  设置所有节点展开状态
 * @param isExpend true展开  false收起
 */
void GY_IdTreeView::setAllRowExpendState(const bool isExpend)
{
    foreach(QList<QStandardItem*> rowItemList,m_TreeNodeInfo)
    {
        if(rowItemList[0]->hasChildren())
        {
            setExpanded(rowItemList[0]->index(),isExpend);
        }
    }
}
//-----------------------------复选框接口-----------------------------------------
/**
 * @brief setCheckable  设置是否显示复选框
 * @param isCheckable  ture显示 false不显示
 */
void GY_IdTreeView::setCheckable(const bool isCheckable)
{
    if(m_IsCheckable==isCheckable)
    {
        return;
    }
    m_IsCheckable=isCheckable;
    //设置现有行的是否显示复选框
    foreach(QList<QStandardItem*> rowItemList,m_TreeNodeInfo)
    {
        rowItemList[0]->setCheckable(true);
    }
}
/**
 * @brief getIsChecked 获取当前是否显示复选框
 * @return 返回是否显示复选框
 */
bool GY_IdTreeView::getCheckable()
{
    return m_IsCheckable;
}
/**
 * @brief getCheckedRowIds  获取选中的行id(不包含半选)
 * @return 返回全部id
 */
QVector<QVariant> GY_IdTreeView::getCheckedRowIds()
{
   QVector<QVariant> checkedIdVector;
   foreach(QList<QStandardItem*> rowItemList,m_TreeNodeInfo)
   {
       if(Qt::CheckState::Checked==rowItemList[0]->checkState())
       {
           checkedIdVector<<rowItemList[0]->data(TreeDataType::RowIdData);
       }
   }
   return checkedIdVector;
}
/**
 * @brief setRowCheckState  设置复选框选中行状态
 * @param rowId  节点id
 * @param isCheck  是否选中
 * @return 返回该行是否被选中，true选中，false未被选中
 */
bool GY_IdTreeView::setRowCheckState(const QVariant &rowId, const bool isCheck)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    if(m_TreeNodeInfo.value(rowId)[0]->checkState()==(isCheck?(Qt::CheckState::Checked):(Qt::CheckState::Unchecked)))
    {
        return false;
    }
    m_TreeNodeInfo.value(rowId)[0]->setCheckState(isCheck?(Qt::CheckState::Checked):(Qt::CheckState::Unchecked));
    //设置子节点复选框状态
    setAllchildNodeCheckState(m_TreeNodeInfo.value(rowId)[0]);
    //跟新到顶层父节点复选框状态
    updateTopParentNodeCheckState(m_TreeNodeInfo.value(rowId)[0]->parent());
    return true;
}
/**
 * @brief getRowCheckState  获取复选框选中行状态
 * @param rowId  节点id
 * @return 返回该行是否被选中，true选中，false未被选中
 */
bool GY_IdTreeView::getRowCheckState(const QVariant &rowId,Qt::CheckState& checkedState)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    checkedState=m_TreeNodeInfo.value(rowId)[0]->checkState();
    return true;
}
/**
 * @brief setTreeAllChecked 复选框全选/全不选
 * @param check 是否全选/全不选
 */
void GY_IdTreeView::setTreeAllChecked(const bool isChecked)
{
    Qt::CheckState checkState=isChecked?(Qt::CheckState::Checked):(Qt::CheckState::Unchecked);
    foreach(QList<QStandardItem*> rowItemList,m_TreeNodeInfo)
    {
        if(checkState!= rowItemList[0]->checkState())
        {
            rowItemList[0]->setCheckState(checkState);
        }
    }
}
/**
 * @brief setAllchildNodeCheckState 设置所有子节点的复选框状态
 * @param pItem 节点对象
 */
void GY_IdTreeView::setAllchildNodeCheckState(QStandardItem *pItem)
{
    for(int i=0;i<pItem->rowCount();i++)
    {
        if(pItem->child(i)->parent()->checkState()!= pItem->child(i)->checkState())
        {
            pItem->child(i)->setCheckState(pItem->checkState());
            setAllchildNodeCheckState(pItem->child(i));
        }
    }
}
/**
 * @brief updateTopParentNodeCheckState 更新递归至顶层的所有父级节点的复选状态
 * @param pItem 当前节点item
 */
void GY_IdTreeView::updateTopParentNodeCheckState(QStandardItem *pItem)
{
    if(nullptr==pItem)
    {
        return ;
    }
    bool checked=true , unchecked=true , halfcheck = false;
    for(int i=0;i<pItem->rowCount();i++)
    {
        if(pItem->child(i)->checkState() == Qt::CheckState::Checked)
        {
            unchecked = false;
        }
        else if(pItem->child(i)->checkState() == Qt::CheckState::Unchecked)
        {
            checked = false;
        }
        else
        {
            halfcheck = true;
            break;
        }
    }

    pItem->setCheckState((halfcheck||(!checked&&!unchecked))?(Qt::CheckState::PartiallyChecked):(checked?(Qt::CheckState::Checked):(Qt::CheckState::Unchecked)));
    updateTopParentNodeCheckState(pItem->parent());
}


//-------------------------值改变接口-------------------------------
/**
 * @brief cellDataChangeSlot 单元格数据改变
 * @param topLeft  左上索引以
 * @param bottomRight 右下索引
 * @param roles 数据类型
 */
void GY_IdTreeView::cellDataChangeSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    //判定只更改了1个Item
    if(topLeft==bottomRight)
    {
        QStandardItem* pItem=m_TreeNodeInfo.value(topLeft.siblingAtColumn(0).data(TreeDataType::RowIdData)).at(topLeft.column());
        //判定是复选框改变
        if(roles.size()==0)
        {
            return ;
        }
        if(roles[0]==TreeDataType::CheckStateData&&topLeft.column()==0)
        {
            m_pModel->blockSignals(true);
            updateTopParentNodeCheckState(pItem->parent());
            setAllchildNodeCheckState(pItem);
            m_pModel->blockSignals(false);
            viewport()->update();
        }
        //判定是用户更改了文本框内容
        else if(roles[0]==TreeDataType::DisplayData)
        {
            pItem->setData(pItem->data(TreeDataType::DisplayData),TreeDataType::TransferData);
            emit sgl_CellValueChange(pItem->index().siblingAtColumn(0).data(TreeDataType::RowIdData),pItem->index().column(),pItem->data());
        }
    }
}



